package com.myrpc.transfer.transport.socket;

import com.myrpc.autoconfig.MyRpcConfigEntity;
import com.myrpc.util.PropertiesUtil;
import com.myrpc.util.ThreadPoolConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.DependsOn;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * 套接字Socket 请求调用客户端实现
 */
@Slf4j
@Component("SocketRpcServer")
@DependsOn({"MyRpcConfigEntity"})
public class SocketRpcServer {
    private ThreadPoolExecutor threadPool;
    private int port;
    @Autowired
    private MyRpcConfigEntity rpcConfig;
    public SocketRpcServer(){
//        this.port = Integer.parseInt(PropertiesUtil.getConfigProperty("serverPort"));
    }
    public void start(){
        this.port = Integer.parseInt(rpcConfig.getServerPort());
        try(ServerSocket server = new ServerSocket()){
            //创建线程池
            ThreadPoolConfig config = new ThreadPoolConfig();
            this.threadPool = new ThreadPoolExecutor(config.getCorePoolSize(),
                    config.getMaximumPoolSize(),
                    config.getKeepAliveTime(),
                    config.getTimeUnit(),
                    new ArrayBlockingQueue<>(config.getBlockingQueueCapacity()),
                    new ThreadPoolExecutor.CallerRunsPolicy());
            log.info("已创建线程池[{}]", this.threadPool);
            String hostAddress = InetAddress.getLocalHost().getHostAddress();
            InetSocketAddress inetSocketAddress = new InetSocketAddress(hostAddress, this.port);
            server.bind(inetSocketAddress);
            log.info("开始监听Rpc请求在[{}]", inetSocketAddress.toString());
            Socket socket;
            while ((socket = server.accept()) != null){
                log.info("Client {} is arrived", socket.getInetAddress());
                //执行到达的任务
                threadPool.execute(new SocketRpcRequestHandlerRunnable(socket));
            }
            //关闭线程池
            threadPool.shutdown();
        }catch (IOException e){
            log.error("Socket服务器IO异常", e);
        }
    }

}
